package com.kede.app.service.impl;

import com.kede.app.domain.SupplieStoreLog;
import com.kede.app.domain.Supplies;
import com.kede.app.domain.SuppliesStore;
import com.kede.app.domain.ZhiUserCertified;
import com.kede.app.repository.SupplieStoreLogRepository;
import com.kede.app.repository.SuppliesRepository;
import com.kede.app.repository.SuppliesStoreRepository;
import com.kede.app.repository.ZhiUserCertifiedRepository;
import com.kede.app.service.SupplieStoreLogService;
import com.kede.app.service.dto.SupplieStoreLogDto;
import com.kede.app.service.dto.SupplieStoreLogQueryCriteria;
import com.kede.app.service.mapstruct.SupplieStoreLogMapper;
import com.kede.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
* @description 服务实现
* @author Pr.li
* @date 2023-06-06
**/
@Service
@RequiredArgsConstructor
public class SupplieStoreLogServiceImpl implements SupplieStoreLogService {

    private final SupplieStoreLogRepository supplieStoreLogRepository;
    private final SupplieStoreLogMapper supplieStoreLogMapper;

    private final SuppliesRepository suppliesRepository;
    private final SuppliesStoreRepository suppliesStoreRepository;

    private final ZhiUserCertifiedRepository zhiUserCertifiedRepository;

    @Override
    public Map<String,Object> queryAll(SupplieStoreLogQueryCriteria criteria, Pageable pageable){
        Page<SupplieStoreLog> page = supplieStoreLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        page.getContent().forEach(supplieStoreLog -> {
            ZhiUserCertified store = zhiUserCertifiedRepository.findByUserId(supplieStoreLog.getStoreId());
            supplieStoreLog.setStore(store);
        });
        return PageUtil.toPage(page.map(supplieStoreLogMapper::toDto));
    }

    @Override
    public List<SupplieStoreLogDto> queryAll(SupplieStoreLogQueryCriteria criteria){
        return supplieStoreLogMapper.toDto(supplieStoreLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public SupplieStoreLogDto findById(Integer id) {
        SupplieStoreLog supplieStoreLog = supplieStoreLogRepository.findById(id).orElseGet(SupplieStoreLog::new);
        ValidationUtil.isNull(supplieStoreLog.getId(),"SupplieStoreLog","id",id);
        return supplieStoreLogMapper.toDto(supplieStoreLog);
    }

    private static  final int ZERO = 0;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SupplieStoreLogDto create(SupplieStoreLog resources) {
        Optional<Supplies> suppliesOptional = suppliesRepository.findById(resources.getSupplieId());
        if (suppliesOptional.isPresent()) {
            Supplies supplie = suppliesOptional.get();
            if (supplie.getCurrNum() < resources.getNum()){
                throw new RuntimeException("库存不足");
            }else {
                //正常 给 这个门店的物资汇总
                SuppliesStore suppliesStore = suppliesStoreRepository.findDistinctBySupplieIdAndStoreId(resources.getSupplieId(), resources.getStoreId());
                if (suppliesStore == null){
                    suppliesStore = new SuppliesStore();
                    suppliesStore.setInitNum(ZERO);
                    suppliesStore.setCurrNum(ZERO);
                }
                // 统计一共发到这家门店的数量
                int i = suppliesStore.getInitNum() + resources.getNum();
                suppliesStore.setInitNum(i);
                int cunum = suppliesStore.getCurrNum() + resources.getNum();
                suppliesStore.setCurrNum(cunum);
                suppliesStore.setStoreId(resources.getStoreId());
                suppliesStore.setSupplieId(resources.getSupplieId());
                suppliesStore.setCreateBy(SecurityUtils.getCurrentUsername());
                suppliesStore.setUpdateBy(SecurityUtils.getCurrentUsername());
                //下面这个表中 的userid 就是 后续逻辑用的 storeId
                ZhiUserCertified storeCertify = zhiUserCertifiedRepository.findByUserId(resources.getStoreId());
                suppliesStore.setLng(storeCertify.getLng());
                suppliesStore.setLat(storeCertify.getLat());
                Supplies supplies = suppliesRepository.getById(resources.getSupplieId());
                if (supplies!=null){
                    suppliesStore.setSupplieName(supplies.getSupplieName());
                    supplies.setCurrNum(supplies.getCurrNum() - resources.getNum());
                    suppliesRepository.save(supplies);
                }
                suppliesStoreRepository.save(suppliesStore);
            }
        }else {
            throw new RuntimeException("物资不存在");
        }


        return supplieStoreLogMapper.toDto(supplieStoreLogRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SupplieStoreLog resources) {
        SupplieStoreLog supplieStoreLog = supplieStoreLogRepository.findById(resources.getId()).orElseGet(SupplieStoreLog::new);
        ValidationUtil.isNull( supplieStoreLog.getId(),"SupplieStoreLog","id",resources.getId());
        supplieStoreLog.copy(resources);
        supplieStoreLogRepository.save(supplieStoreLog);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            supplieStoreLogRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<SupplieStoreLogDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (SupplieStoreLogDto supplieStoreLog : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("物资id", supplieStoreLog.getSupplieId());
            map.put("门店id", supplieStoreLog.getStoreId());
            map.put("这次门店入库多少", supplieStoreLog.getNum());
            map.put("门店入库图片信息", supplieStoreLog.getImg());
            map.put(" createTime",  supplieStoreLog.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}